#include "maindialog.h"
#include "ui_maindialog.h"
#include "qss.h"

MainDialog::MainDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MainDialog)
{
    ui->setupUi(this);

    initialWidgets();
    initialSignalSlot();

    //V1.1 焦岳修复，窗口关闭后自动调用析构，不加不会调用，不断开TCP链接
    setAttribute(Qt::WA_DeleteOnClose);
}

void MainDialog::setHaaSModuleVisible(bool visible)
{
    if(visible)
        ui->tabWidget_haas->show();
    else
        ui->tabWidget_haas->hide();
}

MainDialog::~MainDialog()
{
    if(socket !=NULL)
    {
        disconnect(socket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot()));
        if(socket->isOpen())
            socket->close();
    }
    delete ui;
}

/**
 * @brief MainDialog::connect2Host 连接到主机
 * @param ip IP地址
 * @param port 端口号
 * @param type 连接设备类型
 */
void MainDialog::connect2Host(QString ip, int port, HostType type)
{
    if(socket == NULL)
        socket = new QTcpSocket(this);
    else // 断舍离
    {
        disconnect(socket,SIGNAL(connected()),this,SLOT(connectedSlot()));
        disconnect(socket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot()));
        disconnect(socket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
    }
    connect(socket,SIGNAL(connected()),this,SLOT(connectedSlot()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));

    tempHostType = type;
    socket->connectToHost(ip,port);
}

/**
 * @brief MainDialog::initialSignalSlot
 * 初始化信号槽
 */
void MainDialog::initialSignalSlot()
{
    connect(ui->listWidget, SIGNAL(currentRowChanged(int)),
            ui->stackedWidget, SLOT(setCurrentIndex(int)));
    connect(ui->slider_led,SIGNAL(valueChanged(int)),
            this,SLOT(ledValueChangedSlot(int)));
    connect(ui->slider_led_2,SIGNAL(valueChanged(int)),
            this,SLOT(led2ValueChangedSlot(int)));
    connect(ui->slider_led_3,SIGNAL(valueChanged(int)),
            this,SLOT(led3ValueChangedSlot(int)));
    connect(ui->slider_buzzer,SIGNAL(valueChanged(int)),
            this,SLOT(buzzerValueChangedSlot(int)));
    connect(connectBtnGroup,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsConnectClickedSlot(int)));
    connect(receiveBtnGroup,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsReceiveClickedSlot(int)));
}

/**
 * @brief MainDialog::setQssStyle
 * 初始化各种组件
 */
void MainDialog::initialWidgets()
{
    for(int i = 0;i < ui->listWidget->count();i++)
    {
        ui->listWidget->item(i)->setSizeHint(QSize(0, 100));
    }
    ui->listWidget->setStyleSheet(QListWidget_STYTLE);
    ui->pushButton_haas->setStyleSheet(QPushButton_STYTLE);
    ui->pushButton_server->setStyleSheet(QPushButton_STYTLE);
    ui->slider_led->setStyleSheet(QSlider_STYTLE);
    ui->slider_led_2->setStyleSheet(QSlider_STYTLE);
    ui->slider_led_3->setStyleSheet(QSlider_STYTLE);
    ui->slider_buzzer->setStyleSheet(QSlider_STYTLE);
    ui->label_led->setEnabled(false);
    ui->label_led_2->setEnabled(false);
    ui->label_led_3->setEnabled(false);
    ui->label_buzzer->setEnabled(false);

    ui->btnImage_buzzer->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_compass->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_height->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_humid->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_led->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_light->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_press->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_temp->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_votage->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_x->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_y->setStyleSheet(QButtonImage_STYTLE);
    ui->btnImage_z->setStyleSheet(QButtonImage_STYTLE);

    connectBtnGroup = new QButtonGroup(this);
    connectBtnGroup->addButton(ui->pushButton_server,1);
    connectBtnGroup->addButton(ui->pushButton_haas,2);

    receiveBtnGroup = new QButtonGroup(this);
    receiveBtnGroup->addButton(ui->btnImage_led,1);
    receiveBtnGroup->addButton(ui->btnImage_buzzer,2);
    receiveBtnGroup->addButton(ui->btnImage_votage,3);
    receiveBtnGroup->addButton(ui->btnImage_temp,4);
    receiveBtnGroup->addButton(ui->btnImage_humid,5);
    receiveBtnGroup->addButton(ui->btnImage_press,6);
    receiveBtnGroup->addButton(ui->btnImage_height,7);
    receiveBtnGroup->addButton(ui->btnImage_light,8);
    receiveBtnGroup->addButton(ui->btnImage_x,9);
    receiveBtnGroup->addButton(ui->btnImage_y,10);
    receiveBtnGroup->addButton(ui->btnImage_z,11);
    receiveBtnGroup->addButton(ui->btnImage_compass,12);

    ui->lineEditServerPort->setValidator(new QIntValidator(this));
    ui->lineEditHaaSPort->setValidator(new QIntValidator(this));

    // 复原上次输入
    QSettings setting("config.ini",QSettings::IniFormat);
    setting.setIniCodec(QTextCodec::codecForName("UTF-8"));

    setting.beginReadArray("MainDialog");
    QString ip = setting.value("server ip").toString();
    ui->lineEditServerIp->setText(ip);
    QString port = setting.value("server port").toString();
    ui->lineEditServerPort->setText(port);

    ip = setting.value("haas ip").toString();
    ui->lineEditHaaSIp->setText(ip);
    port = setting.value("haas port").toString();
    ui->lineEditHaaSPort->setText(port);
    setting.endArray();

    // 不连接就不给进入控制和接收的page
    ui->page_control->setEnabled(false);
    ui->page_receive->setEnabled(false);
}

/**
 * @brief MainDialog::showMessage 方便弹出QMessageBox
 * @param type 1:question 2:infortion 3:warning 4:critical
 * @param msg 信息内容
 */
void MainDialog::showMessage(QString msg,MessageType type = MessageType::WARNING)
{
    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    time.append("\n");
    if(type == MessageType::QUESTION)
    {
        QMessageBox::question(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::INFORMATION)
    {
        QMessageBox::information(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::WARNING)
    {
        QMessageBox::warning(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::CRITICAL)
    {
        QMessageBox::critical(this,this->windowTitle(),msg.prepend(time));
    }
}

void MainDialog::btnsConnectClickedSlot(int id)
{
    if(id == 1) // 连接Server
    {
        // 获取并判断用户输入的参数是否正确
        QString text = ui->lineEditServerIp->text();
        text = text.trimmed();
        QHostAddress ip;
        if(!ip.setAddress(text))
        {
            showMessage("请输入正确的IP地址！");
            return;
        }

        int port = ui->lineEditServerPort->text().toInt();
        if(port<=0 || port>65535)
        {
            showMessage("请输入正确的端口号！");
            return;
        }
        // 尝试连接Server
        connect2Host(ip.toString(),port,HostType::SERVER);

        // 记住输入
        QSettings setting("config.ini",QSettings::IniFormat);
        setting.setIniCodec(QTextCodec::codecForName("UTF-8"));

        setting.beginWriteArray("MainDialog");
        setting.setValue("server ip",text);
        setting.setValue("server port",port);
        setting.endArray();
    }else if(id == 2) // 连接haas
    {
        // 获取并判断用户输入的参数是否正确
        QString text = ui->lineEditHaaSIp->text();
        text = text.trimmed();
        QHostAddress ip;
        if(!ip.setAddress(text))
        {
            showMessage("请输入正确的IP地址！");
            return;
        }

        int port = ui->lineEditHaaSPort->text().toInt();
        if(port<=0 || port>65535)
        {
            showMessage("请输入正确的端口号！");
            return;
        }
        // 尝试连接HaaS
        connect2Host(ip.toString(),port,HostType::HAAS);

        // 记住IP
        QSettings setting("config.ini",QSettings::IniFormat);
        setting.setIniCodec(QTextCodec::codecForName("UTF-8"));

        setting.beginWriteArray("MainDialog");
        setting.setValue("haas ip",text);
        setting.setValue("haas port",port);
        setting.endArray();
    }
}

void MainDialog::ledValueChangedSlot(int value)
{
    if(value == 0)
        ui->label_led->setEnabled(false);
    else
        ui->label_led->setEnabled(true);

    if(socket == NULL)
        return;
    if(!socket->isOpen())
        return;

    struct node obj;
    strcpy(obj.name,"led1");
    obj.type = 1;
    if(value == 0)
        obj.ival = 0;
    else
        obj.ival = 1;
    socket->write((char *)&obj, sizeof(obj));
}

void MainDialog::led2ValueChangedSlot(int value)
{
    if(value == 0)
        ui->label_led_2->setEnabled(false);
    else
        ui->label_led_2->setEnabled(true);

    if(socket == NULL)
        return;
    if(!socket->isOpen())
        return;

    struct node obj;
    strcpy(obj.name,"led2");
    obj.type = 1;
    if(value == 0)
        obj.ival = 0;
    else
        obj.ival = 1;
    socket->write((char *)&obj, sizeof(obj));
}

void MainDialog::led3ValueChangedSlot(int value)
{
    if(value == 0)
        ui->label_led_3->setEnabled(false);
    else
        ui->label_led_3->setEnabled(true);

    if(socket == NULL)
        return;
    if(!socket->isOpen())
        return;

    struct node obj;
    strcpy(obj.name,"led3");
    obj.type = 1;
    if(value == 0)
        obj.ival = 0;
    else
        obj.ival = 1;
    socket->write((char *)&obj, sizeof(obj));
}

void MainDialog::buzzerValueChangedSlot(int value)
{
    if(value == 0)
        ui->label_buzzer->setEnabled(false);
    else
        ui->label_buzzer->setEnabled(true);

    if(socket == NULL)
        return;
    if(!socket->isOpen())
        return;

    struct node obj;
    strcpy(obj.name,"beep");
    obj.type = 1;
    if(value == 0)
        obj.ival = 0;
    else
        obj.ival = 1;
    socket->write((char *)&obj, sizeof(obj));
}

void MainDialog::btnsReceiveClickedSlot(int id)
{
    if(id == 1)
    {
        // LED灯
        dialog = new ChartDialog(SensorType::LED,this);
    }else if(id == 2)
    {
        // 蜂鸣器
        dialog = new ChartDialog(SensorType::BUZZER,this);
    }else if(id == 3)
    {
        // 电压
        dialog = new ChartDialog(SensorType::VOLTAGE,this);
    }else if(id == 4)
    {
        // 温度
        dialog = new ChartDialog(SensorType::TEMPERATURE,this);
    }else if(id == 5)
    {
        // 湿度
        dialog = new ChartDialog(SensorType::HUMIDITY,this);
    }else if(id == 6)
    {
        // 大气压
        dialog = new ChartDialog(SensorType::PRESSURE,this);
    }else if(id == 7)
    {
        // 海拔
        dialog = new ChartDialog(SensorType::HEIGHT,this);
    }else if(id == 8)
    {
        // 光线
        dialog = new ChartDialog(SensorType::LIGHT,this);
    }else if(id == 9)
    {
        // X
        dialog = new ChartDialog(SensorType::X,this);
    }else if(id == 10)
    {
        // Y
        dialog = new ChartDialog(SensorType::Y,this);
    }else if(id == 11)
    {
        // Z
        dialog = new ChartDialog(SensorType::Z,this);
    }else if(id == 12)
    {
        // 罗盘
        dialog = new ChartDialog(SensorType::COMPASS,this);
    }
    dialog->show();
}

void MainDialog::connectedSlot()
{
    currentHostType = tempHostType;
    if(currentHostType == HostType::SERVER)
    {
        ui->tabWidget_haas->setEnabled(false);
        ui->pushButton_server->setText("已连接");
        ui->pushButton_server->setEnabled(false);
    }else if(currentHostType == HostType::HAAS)
    {
        ui->tabWidget_server->setEnabled(false);
        ui->pushButton_haas->setText("已连接");
        ui->pushButton_haas->setEnabled(false);
    }
    ui->page_control->setEnabled(true);
    ui->page_receive->setEnabled(true);
}

void MainDialog::disconnectedSlot()
{
    if(currentHostType == HostType::SERVER)
    {
        ui->tabWidget_haas->setEnabled(true);
        ui->pushButton_server->setText("连接");
        ui->pushButton_server->setEnabled(true);
    }else if(currentHostType == HostType::HAAS)
    {
        ui->tabWidget_server->setEnabled(true);
        ui->pushButton_haas->setText("连接");
        ui->pushButton_haas->setEnabled(true);
    }
    ui->page_control->setEnabled(false);
    ui->page_receive->setEnabled(false);
    ui->stackedWidget->setCurrentIndex(0);
    ui->listWidget->setCurrentRow(0);

    showMessage("连接已断开！",MessageType::CRITICAL);
    currentHostType = HostType::NONE;
}

void MainDialog::readyReadSlot()
{
    // 如果数据可用就读
    while(socket->bytesAvailable()>0)
    {
        struct node obj;
        socket->read((char* )&obj,sizeof(obj));
        qDebug() << "接收到数据" << obj.name << obj.type << obj.ival << obj.fval << obj.text;
        // 清空读缓存区
//        qDebug() << "清空读缓存区：" << socket->readAll();
        // 展示在公屏上
        QString typeName = obj.name;
        if(typeName == "temp")
        {
            ui->labelTemperature->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::TEMPERATURE,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[0] = obj;
        }
        else if(typeName == "hum")
        {
            ui->labelHumidity->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::HUMIDITY,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[1] = obj;
        }
        else if(typeName == "ill")
        {
            ui->labelLight->setText(QString::number(obj.ival));
            dbHelper.addRow(SensorType::LIGHT,obj.ival,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[2] = obj;
        }
        else if(typeName == "atmos")
        {
            ui->labelPressure->setText(QString::number(obj.ival));
            dbHelper.addRow(SensorType::PRESSURE,obj.ival,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[3] = obj;
        }
        else if(typeName == "asl")
        {
            ui->labelHeight->setText(QString::number(obj.ival));
            dbHelper.addRow(SensorType::HEIGHT,obj.ival,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[4] = obj;
        }
        else if(typeName == "adc")
        {
            ui->labelVotage->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::VOLTAGE,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[5] = obj;
        }
        else if(typeName == "x")
        {
            ui->labelX->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::X,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[6] = obj;
        }
        else if(typeName == "y")
        {
            ui->labelY->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::Y,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[7] = obj;
        }
        else if(typeName == "z")
        {
            ui->labelZ->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::Z,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[8] = obj;
        }
        else if(typeName == "compass")
        {
            // 待定
            ui->labelCompass->setText(QString::number(obj.fval,'f',2));
            dbHelper.addRow(SensorType::COMPASS,obj.fval,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[9] = obj;
        }
        else if(typeName == "led1")
        {
            int ledStatus = obj.ival;
            if(ledStatus == 1)
            {
                ui->labelLed->setText("开");
                ui->slider_led->setValue(1);
                ui->label_led->setEnabled(true);
            }
            else
            {
                ui->labelLed->setText("关");
                ui->slider_led->setValue(0);
                ui->label_led->setEnabled(false);
            }
            dbHelper.addRow(SensorType::LED,obj.ival,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[10] = obj;
        }
        else if(typeName == "beep")
        {
            int buzzerStatus = obj.ival;
            if(buzzerStatus == 1)
            {
                ui->labelBuzzer->setText("开");
                ui->slider_buzzer->setValue(1);
                ui->label_buzzer->setEnabled(true);
            }
            else
            {
                ui->labelBuzzer->setText("关");
                ui->slider_buzzer->setValue(0);
                ui->label_buzzer->setEnabled(false);
            }
            dbHelper.addRow(SensorType::BUZZER,obj.ival,QDateTime::currentDateTime());
            if(dialog != NULL)
                dialog->currentNode[11] = obj;
        }
    }

}
